Event Driven Architecture 이벤트 기반 아키텍처 도입 {curinginnos}
문제정의
WHY:
현재의 시스템은 강한 결합 구조로 인해 변경에 취약하며, 예약, 결제, 알림, 통계 등 다양한 비즈니스 도메인이 서로 긴밀하게 얽혀있다. 이로 인해 하나의 기능 변경이 다수의 모듈에 영향을 주며, 장애 발생 시 전체 서비스 안정성에도 영향을 미친다. 이벤트 기반 아키텍처를 도입하면 도메인 간 결합도를 낮추고, 비동기 처리를 통해 성능과 확장성, 유지보수성을 개선할 수 있다.
WHERE:
- NestJS 기반의 서버 애플리케이션 전반
- 특히 결제 처리, 예약 생성/변경, 사용자 알림 발송, 데이터 동기화/통계 수집 등이 이벤트 처리의 핵심 대상이 될 수 있다.
WHAT:
- 결제 완료 시 예약 확정, 쿠폰 소모, 정산 정보 업데이트, 알림 발송 등의 후속 처리를 이벤트로 분리
- 하나의 액션(예: 결제완료)이 여러 후속 작업을 유발할 경우, 이벤트 발행 → 이벤트 핸들러에서 처리 방식으로 구조 분리
- 이벤트 로그 저장 (Outbox 패턴 고려) 및 재처리 전략(최소 1회 처리 보장 등)을 통해 데이터 일관성 보장
UseCase
처음 이벤트 기반 아키텍처가 도입될 때 예상되는 사용사례는 어떤 것이 있나?
-
푸시알림, 알림톡, SMS 발송 분리
→ 예약/결제/환불 등의 행위 이후 알림을 직접 호출하지 않고, NotificationRequestedEvent를 발행하여 알림 서비스가 수신하여 처리
-
지연된 예약 확정 (예: 다대일 레슨의 더치페이)
→ 모든 참여자가 결제를 마칠 때까지 PendingReservationEvent 상태로 유지하고, 최종 조건이 충족되면 ReservationConfirmedEvent 발생
-
초대 기반 참여 로직
→ 휴대폰 번호로 초대장을 보낸 뒤, 수락 여부에 따라 다른 이벤트 (InviteAcceptedEvent, InviteRejectedEvent) 발생
-
Payment History 추적 및 정산 처리 분리
→ 결제 성공 시 PaymentCompletedEvent 발생 → 정산 모듈에서 이 이벤트를 구독하여 Settlement 정보를 생성
-
통계 집계 로직 분리
→ 예약, 결제, 환불, 출입 등 주요 도메인 이벤트를 기반으로 StatsUpdatedEvent 등을 발행하고, 통계 처리 모듈에서 비동기 집계 수행
AS-IS, TO-BE
항목 | AS-IS (기존 방식) | TO-BE (이벤트 기반 아키텍처 도입 후) |
---|---|---|
결제 처리 | PaymentService가 예약확정/알림/정산을 직접 호출 | PaymentService는 PaymentCompletedEvent만 발행, 나머지는 이벤트 핸들러에서 처리 |
예약 확정 | 예약 도중 결제 실패 시 예외 상황 처리 어려움 | ReservationRequestedEvent로 흐름 단순화, 실패는 ReservationFailedEvent로 처리 |
알림 발송 | 각 서비스 로직에서 직접 발송 로직 호출 | NotificationService가 이벤트 수신 후 자체 큐를 통해 발송 관리 |
통계 반영 | 실시간 DB write 또는 cron batch job | EventLog 기반 비동기 집계 가능, 성능 및 일관성 향상 |
예상 개발기간, 소요시간
주요 작업 항목 | 예상 소요시간 |
---|---|
이벤트 메시지 구조 설계 및 표준화 (EventPayload, EventType 등) | 1~2일 |
EventBus 추상화 및 in-memory adapter 구현 (초기용) | 1일 |
주요 이벤트 정의 (PaymentCompletedEvent, ReservationRequestedEvent 등) | 1~2일 |
이벤트 발행 로직 적용 (결제, 예약 등 핵심 흐름) | 3~5일 |
알림 서비스 리팩토링 (이벤트 수신형으로 변경) | 2~3일 |
테스트 케이스 작성 및 QA 환경 배포 | 2~3일 |
총 예상 기간 | 약 1014일 (주말 제외 기준 23주 소요) |
향후 Kafka 등 메시지 브로커를 도입할 경우 Outbox 패턴 도입 및 장애 대응 전략 설계에 별도 시간이 소요됨 (2~3주 추가)